package com.cloudlinkin.util.error;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 上报异常控制器 同一控制器记录异常每大于5次 且间隔时长大于timeInterval(banx)就就触发上报
 * 
 */
public class RecordingExceptionControl {

	private static long timeInterval = TimeUnit.MINUTES.toMillis(30); // 发送时间间隔30分钟
	// private static AtomicInteger errorCount = new AtomicInteger(0); //
	// 异常发生的次数

	private static ConcurrentHashMap<String, AtomicInteger> errorCount = new ConcurrentHashMap<>();
	private static ConcurrentHashMap<String, AtomicLong> startTime = new ConcurrentHashMap<>();

	private RecordingExceptionControl() {
	}

	/**
	 * 控制上报异常 同一个控制器 异常次数每超过5时且间隔时长大于timeInterval(半小时)上报异常
	 * 
	 * @param content
	 *            要上报的内容
	 * @throws IOException
	 */
	public synchronized static void controlRecordingException(String key, String content) {

		AtomicInteger count = errorCount.get(key);
		if (count == null) {
			errorCount.put(key, (count = new AtomicInteger(0)));
		}

		AtomicLong start = startTime.get(key);
		if (start == null) {
			startTime.put(key, (start = new AtomicLong(0)));
		}

		if ((System.currentTimeMillis() - start.get()) > timeInterval) {

			if (count.get() >= 4) {

				try {

					RecordingExceptionUtil.recording(content);

				} catch (Exception e) {
					e.printStackTrace();
					return;
				}

				// 更新时间
				start.getAndSet(System.currentTimeMillis());
			} else {

				// 更新计数
				count.incrementAndGet();

			}

		}

	}

	/**
	 * 重置异常统计次数
	 */
	public static void controlClear() {
		for (Map.Entry<String, AtomicInteger> count : errorCount.entrySet()) {
			count.getValue().getAndSet(0);
		}
	}

	/**
	 * 关于引用数据类型的使用的基本知识 示例
	 * 
	 * @param args
	 */
	public static void main(String[] args) {

		AtomicInteger count = new AtomicInteger(0);

		errorCount.put("test", count);

		// 增加次数
		count.incrementAndGet();
		count.incrementAndGet();
		count.incrementAndGet();
		count.incrementAndGet();
		count.incrementAndGet();
		// 直接输出map内对象的值
		System.out.println(errorCount.get("test").get());

		// 重置所有次数
		for (Map.Entry<String, AtomicInteger> count1 : errorCount.entrySet()) {
			count1.getValue().getAndSet(0);
		}

		// 直接输出map内对象的值
		System.out.println(errorCount.get("test").get());

	}

}